﻿Imports System.ComponentModel
Imports System.IO
Imports System.Net
Imports System.Threading
Imports System.Xml
Imports LINKAutoUpdate.dllLib

Public Class FrmAutoUpdate
#Region "类申明变量"
    Private isFinished As Boolean = False
    Private downloadFileList As List(Of DownloadFileInfo) = Nothing
    Private allFileList As List(Of DownloadFileInfo) = Nothing
    Private evtDownload As ManualResetEvent = Nothing
    Private evtPerDonwload As ManualResetEvent = Nothing
    Private clientDownload As WebClient = Nothing
    Private total As Long = 0

    Private nDownloadedTotal As Long = 0

#End Region

#Region "类重构"
    ''' <summary>
    ''' 类重构     
    ''' </summary>
    ''' <param name="downloadFileListTemp"></param>
    ''' <remarks></remarks>
    Public Sub New(ByVal downloadFileListTemp As List(Of DownloadFileInfo))
        InitializeComponent()
        Me.downloadFileList = downloadFileListTemp
        allFileList = New List(Of DownloadFileInfo)()
        For Each file As DownloadFileInfo In downloadFileListTemp
            allFileList.Add(file)
        Next
        total = 0
        nDownloadedTotal = 0
    End Sub

#End Region
    Sub New()
        InitializeComponent()
    End Sub

    Public Overrides Sub ProcessCommand(ByVal cmd As System.Enum, ByVal arg As Object)
        MyBase.ProcessCommand(cmd, arg)
    End Sub

    Public Enum SplashScreenCommand
        SomeCommandId
    End Enum

  
#Region "窗体自定义函数及事件"

    Private Overloads Sub OnFormClosing(ByVal sender As Object, ByVal e As FormClosingEventArgs) Handles MyBase.FormClosing
        If Not isFinished AndAlso DialogResult.No = MessageBox.Show(ConstFile.CANCELORNOT, ConstFile.MESSAGETITLE, MessageBoxButtons.YesNo, MessageBoxIcon.Question) Then
            e.Cancel = True
            Return
        Else
            If clientDownload IsNot Nothing Then clientDownload.CancelAsync()
            evtDownload.[Set]()
            evtPerDonwload.[Set]()
        End If
    End Sub

    Private Sub OnFormLoad(ByVal sender As Object, ByVal e As EventArgs) Handles MyBase.Load
        evtDownload = New ManualResetEvent(True)
        evtDownload.Reset()
        ThreadPool.QueueUserWorkItem(New WaitCallback(AddressOf Me.ProcDownload))
    End Sub

    Private Sub SetProcessBar(ByVal current As Integer, ByVal total As Integer)
'        If Me.progressBarCurrent.InvokeRequired Then
'            Dim cb As DownloadProgress.SetProcessBarCallBack = New DownloadProgress.SetProcessBarCallBack(AddressOf SetProcessBar)
'            Me.Invoke(cb, New Object() {current, total})
'        Else
'            Me.progressBarCurrent.Value = current
'            Me.progressBarTotal.Maximum = total
'            Me.progressBarTotal.Value = total
'        End If
    End Sub

    ''' <summary>
    ''' 下载进度委托函数      
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    ''' <remarks></remarks>
    Private Sub DownProcess(sender As Object, e As DownloadProgressChangedEventArgs)
        SetProcessBar(e.ProgressPercentage, CInt(((nDownloadedTotal + e.BytesReceived) * 100 / total)))
    End Sub

    ''' <summary>
    ''' 下载完成委托函数，显示最后下载结果       
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    ''' <remarks></remarks>
    Private Sub DownCompleted(sender As Object, e As AsyncCompletedEventArgs)
        Try
            DealWithDownloadErrors()
            Dim dfile As DownloadFileInfo = TryCast(e.UserState, DownloadFileInfo)
            nDownloadedTotal += dfile.Size
            Me.SetProcessBar(0, CInt((nDownloadedTotal * 100 / total)))
            evtPerDonwload.[Set]()
        Catch __unusedException1__ As Exception
        End Try
    End Sub

    Private Sub OnCancel(ByVal sender As Object, ByVal e As EventArgs) Handles buttonOk.Click
        ShowErrorAndRestartApplication()
    End Sub

    ''' <summary>
    ''' 显示下载进度        
    ''' </summary>
    ''' <param name="o"></param>
    ''' <remarks></remarks>
    Private Sub ProcDownload(ByVal o As Object)
        Dim tempFolderPath As String = Path.Combine(CommonUnitity.SystemBinUrl, ConstFile.TEMPFOLDERNAME)
        If Not Directory.Exists(tempFolderPath) Then
            Directory.CreateDirectory(tempFolderPath)
        End If

        evtPerDonwload = New ManualResetEvent(False)
        For Each file As DownloadFileInfo In Me.downloadFileList
            total += file.Size
        Next

        Try
            While Not evtDownload.WaitOne(0, False)
                If Me.downloadFileList.Count = 0 Then Exit While
                Dim file As DownloadFileInfo = Me.downloadFileList(0)
                Me.ShowCurrentDownloadFileName(file.FileName)
                '申明下载
                clientDownload = New WebClient()
                '添加现在函数代理接口
                clientDownload.Proxy = System.Net.WebProxy.GetDefaultProxy()
                clientDownload.Proxy.Credentials = CredentialCache.DefaultCredentials
                clientDownload.Credentials = System.Net.CredentialCache.DefaultCredentials
                AddHandler clientDownload.DownloadProgressChanged, AddressOf DownProcess '下载进度,委托SetProcessBar完成显示
                AddHandler clientDownload.DownloadFileCompleted, AddressOf DownCompleted '下载完成，委托函数DownCompleted完成

                evtPerDonwload.Reset()
                Dim tempFolderPath1 As String = CommonUnitity.GetFolderUrl(file)
                If Not String.IsNullOrEmpty(tempFolderPath1) Then
                    tempFolderPath = Path.Combine(CommonUnitity.SystemBinUrl, ConstFile.TEMPFOLDERNAME)
                    tempFolderPath += tempFolderPath1
                Else
                    tempFolderPath = Path.Combine(CommonUnitity.SystemBinUrl, ConstFile.TEMPFOLDERNAME)
                End If

                clientDownload.DownloadFileAsync(New Uri(file.DownloadUrl), Path.Combine(tempFolderPath, file.FileFullName), file)
                evtPerDonwload.WaitOne()
                clientDownload.Dispose()
                clientDownload = Nothing
                Me.downloadFileList.Remove(file)
            End While
        Catch __unusedException1__ As Exception
            ShowErrorAndRestartApplication()
        End Try

        If downloadFileList.Count > 0 Then
            Return
        End If

        DealWithDownloadErrors()
        For Each file As DownloadFileInfo In Me.allFileList
            Dim tempUrlPath As String = CommonUnitity.GetFolderUrl(file)
            Dim oldPath As String = ""
            Dim newPath As String = ""
            Try
                If Not String.IsNullOrEmpty(tempUrlPath) Then
                    oldPath = Path.Combine(CommonUnitity.SystemBinUrl + tempUrlPath.Substring(1), file.FileName)
                    newPath = Path.Combine(CommonUnitity.SystemBinUrl + ConstFile.TEMPFOLDERNAME & tempUrlPath, file.FileName)
                Else
                    oldPath = Path.Combine(CommonUnitity.SystemBinUrl, file.FileName)
                    newPath = Path.Combine(CommonUnitity.SystemBinUrl + ConstFile.TEMPFOLDERNAME, file.FileName)
                End If
                '检查本地文件与服务器文件大小是否一致
                Dim f As System.IO.FileInfo = New FileInfo(newPath)
                If Not file.Size.ToString().Equals(f.Length.ToString()) AndAlso Not file.FileName.ToString().EndsWith(".xml") Then
                    ShowErrorAndRestartApplication()
                End If

                Dim newfilepath As String = String.Empty
                If newPath.Substring(newPath.LastIndexOf(".") + 1).Equals(ConstFile.CONFIGFILEKEY) Then
                    If System.IO.File.Exists(newPath) Then
                        If newPath.EndsWith("_") Then
                            newfilepath = newPath
                            newPath = newPath.Substring(0, newPath.Length - 1)
                            oldPath = oldPath.Substring(0, oldPath.Length - 1)
                        End If
                        IO.File.Move(newfilepath, newPath)
                    End If
                End If

                If IO.File.Exists(oldPath) Then
                    MoveFolderToOld(oldPath, newPath)
                Else
                    If Not String.IsNullOrEmpty(tempUrlPath) Then
                        If Not Directory.Exists(CommonUnitity.SystemBinUrl + tempUrlPath.Substring(1)) Then
                            Directory.CreateDirectory(CommonUnitity.SystemBinUrl + tempUrlPath.Substring(1))
                            MoveFolderToOld(oldPath, newPath)
                        Else
                            MoveFolderToOld(oldPath, newPath)
                        End If
                    Else
                        MoveFolderToOld(oldPath, newPath)
                    End If
                End If
            Catch exp As Exception
            End Try
        Next

        Me.allFileList.Clear()
        If Me.downloadFileList.Count = 0 Then [Exit](True) Else [Exit](False)
        evtDownload.[Set]()
    End Sub

    Private Sub MoveFolderToOld(ByVal oldPath As String, ByVal newPath As String)
        If File.Exists(oldPath & ".old") Then File.Delete(oldPath & ".old")
        If File.Exists(oldPath) Then File.Move(oldPath, oldPath & ".old")
        File.Move(newPath, oldPath)
    End Sub

    Delegate Sub ShowCurrentDownloadFileNameCallBack(ByVal name As String)

    Private Sub ShowCurrentDownloadFileName(ByVal name As String)
'        If Me.labelCurrentItem.InvokeRequired Then
'            Dim cb As DownloadProgress.ShowCurrentDownloadFileNameCallBack = New DownloadProgress.ShowCurrentDownloadFileNameCallBack(AddressOf ShowCurrentDownloadFileName)
'            Me.Invoke(cb, New Object() {name})
'        Else
'            Me.labelCurrentItem.Text = name
        '        End If
        If Me.lblContent.InvokeRequired Then
            Dim cb As DownloadProgress.ShowCurrentDownloadFileNameCallBack = New DownloadProgress.ShowCurrentDownloadFileNameCallBack(AddressOf ShowCurrentDownloadFileName)
            Me.Invoke(cb, New Object() {name})
        Else
            Me.lblContent.Text = name
        End If
    End Sub

    Delegate Sub SetProcessBarCallBack(ByVal current As Integer, ByVal total As Integer)

    Delegate Sub ExitCallBack(ByVal success As Boolean)

    Private Sub [Exit](ByVal success As Boolean)
        If Me.InvokeRequired Then
            Dim cb As DownloadProgress.ExitCallBack = New DownloadProgress.ExitCallBack(AddressOf [Exit])
            Me.Invoke(cb, New Object() {success})
        Else
            Me.isFinished = success
            Me.DialogResult = If(success, DialogResult.OK, DialogResult.Cancel)
            Me.Close()
        End If
    End Sub

    Private Sub DealWithDownloadErrors()
        Try
            Dim config As Config = config.LoadConfig(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, ConstFile.FILENAME))
            Dim client As WebClient = New WebClient()
            client.DownloadString(config.ServerUrl)
        Catch __unusedException1__ As Exception
            ShowErrorAndRestartApplication()
        End Try
    End Sub

    Private Sub ShowErrorAndRestartApplication()
        MessageBox.Show(ConstFile.NOTNETWORK, ConstFile.MESSAGETITLE, MessageBoxButtons.OK, MessageBoxIcon.Information)
        CommonUnitity.RestartApplication()
    End Sub

#End Region
End Class
